package middleware.llvm.instruction;

import middleware.llvm.enums.IRType;
import middleware.llvm.value.FunctionIRType;
import middleware.llvm.value.Value;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 表示函数调用指令
 *
 * @author 杨凯伟
 * @date 2024/10/30
 */
public class CallInstruction extends Instruction {
    private final FunctionIRType func;
    private final List<Value> params = new ArrayList<>();

    public CallInstruction(FunctionIRType func, List<Value> params) {
        super(func.getRetType().clone(), params.toArray(new Value[0]));
        this.func = func;
        this.params.addAll(params);
    }

    public FunctionIRType getFunc() {
        return func;
    }

    public List<Value> getParams() {
        return params;
    }

    @Override
    public void replaceOperand(int pos, Value newOperand) {
        super.replaceOperand(pos, newOperand);
        params.set(pos, newOperand);
    }

    @Override
    public void dump(PrintStream out) {
        out.print("  ");
        if (func.getRetType().getType() != IRType.VOID) {
            out.printf("%s = ", getName());
        }
        out.printf("call %s(", func);

//        assert params.size() == func.getArguments().size();
//        for (int i = 0; i < params.size(); i++) {
//            if (i != 0) {
//                out.print(", ");
//            }
//            var currParam = params.get(i);
//            out.printf("%s", currParam.toString());
//        }
        Iterator<Value> iterator = params.iterator();
        if (iterator.hasNext()) {
            out.printf("%s", iterator.next().toString());
        }
        while (iterator.hasNext()) {
            out.print(", ");
            out.printf("%s", iterator.next().toString());
        }
        out.print(")\n");
    }
}
